﻿/* 
 *  <copyright file="Cam3DOrtho.cs" company="Wesley Jowitt">
 *  
 *  SobrietyEngine: Copyright (c) 2011 Wesley Jowitt
 *  
 *  This software is distributed under a software license.
 *   * As of the creation time of this file, the license in use is the Microsoft Permissive License (Ms-PL) 
 *    * The license can be viewed at:
 *     * License.Txt in the root folder of this project
 *      * http://sobrietyengine.codeplex.com/license
 *       * http://www.microsoft.com/opensource/licenses.mspx
 *       
 *  </copyright>
 *   */


using Microsoft.Xna.Framework;
using SobrietyEngine.Components;
using SobrietyEngine.Components.Controller;
using SobrietyEngine.Events;
using SobrietyEngine.Events.UserActions;
using SobrietyEngine.Guids;


namespace SobrietyEngine.Components.Controller
{
    class Cam3DFreeFly: ControllerCmp, IComponent, IEventListener
    {
      
        IPosition PositionComp = null;
        Vector3 Move = Vector3.Zero;

        IOrientation RotationComp = null;
        Vector3 Rotate = Vector3.Zero;

        CGuid OwningPlayer { get; set; }

        float moveSpeed = 7.0f;
        float rotSpeed = 1.5f;

        public Cam3DFreeFly(CGuid owningPlayer)
            : base()
        {
            OwningPlayer = owningPlayer;
        }

        public override bool InitComponent()
        {
            PositionComp = Actor.Get<IPosition>();
            RotationComp = Actor.Get<IOrientation>();

            //add controller listener events
            RegisterEventListeners();

            return true;
        }
        
        public virtual void RegisterEventListeners()
        {
            Actor.EventRouter.AddEventListener(typeof(Move), this);
            Actor.EventRouter.AddEventListener(typeof(Rotate), this);  
        }


        public new void Remove()
        {
            //remove controller listener events
            UnregisterEventListeners();
        }

        public virtual void UnregisterEventListeners()
        {
            Actor.EventRouter.RemoveEventListener(this);
        }

        public void HandleEvent(Event e)
        {
            //not enabled, exit out
            if (!Enabled)
                return;

            //if this event is not from the owning player
            if (OwningPlayer != e.From)
                return;

            //handle our move event
            if (e.Type == typeof(Move))
            {
                Move m = (Move)e.Data;
                Move = m.MoveBy;
            }

            //handle our rotate event
            if (e.Type == typeof(Rotate))
            {
                Rotate r = (Rotate)e.Data;
                Rotate = r.RotateBy;
            }
        }

        public new void Update(GameTime ElapsedTime)
        {
            float elapsedMs = ((float)ElapsedTime.ElapsedGameTime.Milliseconds) / 1000f;

            //our move and rotates are 2d vectors, from the joystick
            if (Rotate != Vector3.Zero)
            {
                RotationComp.RelativeAxisPitch(Rotate.Y * -1 * rotSpeed * elapsedMs);
                RotationComp.RelativeAxisYaw(Rotate.X * rotSpeed * elapsedMs);
            }
            if (Move != Vector3.Zero)
            {
                Vector3 forwardVec = (moveSpeed * elapsedMs * Move.Y) * RotationComp.Forward;
                Vector3 strafeVec = (moveSpeed * elapsedMs * Move.X) * RotationComp.Right;

                //add to pos
                PositionComp.PositionV3 += forwardVec + strafeVec;
            }
        }

    }
}